package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.core.util.PageUtil;
import com.hbnu.system.mapper.OpusMapper;
import com.hbnu.system.model.dto.CheckBackDTO;
import com.hbnu.system.model.dto.OpusAddDTO;
import com.hbnu.system.model.dto.SearchPageDTO;
import com.hbnu.system.model.dto.UserDTO;
import com.hbnu.system.model.entity.Audit;
import com.hbnu.system.model.entity.Dept;
import com.hbnu.system.model.entity.Opus;
import com.hbnu.system.model.entity.User;
import com.hbnu.system.model.vo.InfoVO;
import com.hbnu.system.service.*;
import com.hbnu.system.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-05-16
 */
@Service
public class OpusServiceImpl extends ServiceImpl<OpusMapper, Opus> implements IOpusService {

    @Autowired
    private IOpusService iOpusService;

    @Autowired private IUserService iUserService;

    @Autowired private IDeptService iDeptService;
    @Autowired
    IAuthorityService iAuthorityService;
    @Autowired
    AuditService auditService;
    @Override
    public boolean addOpus(Opus opus) {
        if(StrUtil.isEmpty(opus.getClassifi()) || StrUtil.isBlank(opus.getClassifi())){
            throw new BaseException("请输入统计分类");
        }
        if(StrUtil.isEmpty(opus.getLeadAuthor()) || StrUtil.isBlank(opus.getLeadAuthor())){
            throw new BaseException("请输入第一作者");
        }
        if(StrUtil.isEmpty(opus.getPublicationNum()) || StrUtil.isBlank(opus.getPublicationNum())){
            throw new BaseException("请输入出版物面数（面");
        }
        if(StrUtil.isEmpty(opus.getOpusCate()) || StrUtil.isBlank(opus.getOpusCate())){
            throw new BaseException("请输入创作著作类别");
        }
        if(StrUtil.isEmpty(opus.getOpusOrigin()) || StrUtil.isBlank(opus.getOpusOrigin())){
            throw new BaseException("请输入作品来源");
        }
        if(StrUtil.isEmpty(opus.getResearchCate()) || StrUtil.isBlank(opus.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(opus.getFirstDiscipline()) || StrUtil.isBlank(opus.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
        if(StrUtil.isEmpty(opus.getSecondaryDiscipline()) || StrUtil.isBlank(opus.getSecondaryDiscipline())){
            throw new BaseException("请输入二级学科");
        }

        Opus one = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusName, opus.getOpusName()));
        if(Objects.nonNull(one) && !(one.getOpusID().equals(opus.getOpusID()))){
            throw new BaseException("出版作品名称重复!");
        }
        opus.setStatus("草稿");
        opus.setAllAuthor(opus.getLeadAuthor());
        //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        //调用一次OpusAuthor的Add接口
        opus.setEnteredDate(LocalDateTime.now());

        return baseMapper.updateById(opus) == 1;

    }

    @Override
    public boolean addOpus(OpusAddDTO opusAddDTO) {
        if(StrUtil.isEmpty(opusAddDTO.getOpusName()) || StrUtil.isBlank(opusAddDTO.getOpusName())){
            throw new BaseException("请输入作品名称");
        }
        if(StrUtil.isEmpty(opusAddDTO.getOpusType()) || StrUtil.isBlank(opusAddDTO.getOpusType())){
            throw new BaseException("请输入创作作品类型");
        }
        if(StrUtil.isEmpty(opusAddDTO.getOrganization()) || StrUtil.isBlank(opusAddDTO.getOrganization())){
            throw new BaseException("请输入所属机构");
        }
        if(StrUtil.isEmpty(opusAddDTO.getPublicationLevel()) || StrUtil.isBlank(opusAddDTO.getPublicationLevel())){
            throw new BaseException("请输入出版社等级");
        }
        if(StrUtil.isEmpty(opusAddDTO.getPublicationName()) || StrUtil.isBlank(opusAddDTO.getPublicationName())){
            throw new BaseException("请输入出版物名称");
        }

        Opus one = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusName, opusAddDTO.getOpusName()));
        if(Objects.nonNull(one)){
            throw new BaseException("该作品名称已被使用!");
        }

        Opus opus = new Opus();
        opus.setOpusName(opusAddDTO.getOpusName());
        opus.setOpusType(opusAddDTO.getOpusType());
        opus.setOrganization(opusAddDTO.getOrganization());
        opus.setPublicationLevel(opusAddDTO.getPublicationLevel());
        opus.setPublicationName(opusAddDTO.getPublicationName());

        //检查各项不可为空选项
        opus.setClassifi("");
        opus.setLeadAuthor("");
        opus.setPublicationNum("");
        opus.setOpusCate("");
        opus.setStatus("草稿");
        opus.setOpusOrigin("");
        opus.setResearchCate("");
        opus.setFirstDiscipline("");
        opus.setSecondaryDiscipline("");
        opus.setEntered("");
////      paper.setDept(iUserService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getName,paper.getEntered())).getDept());
//        String dept = iUserService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getName, paper.getEntered())).getDept();
//        String deptName = iDeptService.getById(dept).getDeptName();
//        identify.setDept(deptName);
        return baseMapper.insert(opus) == 1;
    }

    @Override
    public boolean deleteOpus(String opusID) {
        Opus one = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusID, opusID));
        if (Objects.isNull(one)){
            throw new BaseException("作品编号有误!");
        }
        return baseMapper.deleteById(opusID) == 1;
    }

    @Override
    public boolean updateOpus(Opus opus) {
        if(StrUtil.isEmpty(opus.getClassifi()) || StrUtil.isBlank(opus.getClassifi())){
            throw new BaseException("请输入统计分类");
        }
        //第一作者如果有修改就要对对应的OpusAuthor进行修改！！！
        //！！！！！！！！！！！！！！！！！！！！！！！！！！
        if(StrUtil.isEmpty(opus.getLeadAuthor()) || StrUtil.isBlank(opus.getLeadAuthor())){
            throw new BaseException("请输入第一作者");
        }
        if(StrUtil.isEmpty(opus.getPublicationNum()) || StrUtil.isBlank(opus.getPublicationNum())){
            throw new BaseException("请输入出版物面数（面");
        }
        if(StrUtil.isEmpty(opus.getOpusCate()) || StrUtil.isBlank(opus.getOpusCate())){
            throw new BaseException("请输入创作著作类别");
        }
        if(StrUtil.isEmpty(opus.getOpusOrigin()) || StrUtil.isBlank(opus.getOpusOrigin())){
            throw new BaseException("请输入作品来源");
        }
        if(StrUtil.isEmpty(opus.getResearchCate()) || StrUtil.isBlank(opus.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(opus.getFirstDiscipline()) || StrUtil.isBlank(opus.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
        if(StrUtil.isEmpty(opus.getSecondaryDiscipline()) || StrUtil.isBlank(opus.getSecondaryDiscipline())){
            throw new BaseException("请输入二级学科");
        }

        if(StrUtil.isEmpty(opus.getOpusName()) || StrUtil.isBlank(opus.getOpusName())){
            throw new BaseException("请输入作品名称");
        }
        Opus one = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusName, opus.getOpusName()));
        if(Objects.nonNull(one) && !(one.getOpusID().equals(opus.getOpusID()))){
            throw new BaseException("作品名称重复!");
        }

        if(StrUtil.isEmpty(opus.getOpusType()) || StrUtil.isBlank(opus.getOpusType())){
            throw new BaseException("请输入创作作品类型");
        }
        if(StrUtil.isEmpty(opus.getOrganization()) || StrUtil.isBlank(opus.getOrganization())){
            throw new BaseException("请输入所属机构");
        }
        if(StrUtil.isEmpty(opus.getPublicationLevel()) || StrUtil.isBlank(opus.getPublicationLevel())){
            throw new BaseException("请输入出版社等级");
        }
        if(StrUtil.isEmpty(opus.getPublicationName()) || StrUtil.isBlank(opus.getPublicationName())){
            throw new BaseException("请输入出版物名称");
        }

        return baseMapper.updateById(opus) == 1;
    }

    @Override
    public Opus getOpus(String opusID) {
        Opus opus = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusID, opusID));
        if(Objects.isNull(opus)){
            throw new BaseException("作品编号异常!未查找到该作品");
        }
        return opus;
    }

    @Override
    public boolean checkOpusName(String achievementName) {
        return false;
    }

    @Override
    public IPage<Opus> pageCondition(SearchPageDTO searchPageDTO) {
        IPage<Opus> page = PageUtil.getPage(searchPageDTO.getPageNum(), searchPageDTO.getPageSize());
        LambdaQueryWrapper<Opus> wrapper = Wrappers.lambdaQuery(Opus.class);

        IPage<Opus> opusIPage = baseMapper.selectPage(page, wrapper);
//        IPage<PaperVO> taskVOIPage = iBeanService.copyPageProperties(paperIPage, PaperVO.class);
        List<Opus> records = opusIPage.getRecords();
        List<Opus> OpusS = new ArrayList<>();

        int count = 1;
        int start = searchPageDTO.getPageSize() * (searchPageDTO.getPageNum()-1)+1;
        int end = searchPageDTO.getPageNum() * searchPageDTO.getPageSize();
//        records.forEach(record->{
//            if (count >= start && count <= end){
//                PaperS.add(this.getPaper(record.getPaperID()));
//            }
//        });
        Collections.reverse(records);
        for (Opus record:records) {
            if (count >= start && count <= end){
                OpusS.add(this.getOpus(record.getOpusID()));
            }
            count += 1;
        }


//        Collections.reverse(OpusS);
        opusIPage.setRecords(OpusS);
        opusIPage.setTotal(records.size());
        return opusIPage;
    }

    @Override
    public Boolean schoolCheckPass(String token,String opusID) {
        Opus opus = iOpusService.getOpus(opusID);
        if (Objects.isNull(opus)){
            throw new BaseException("该作品编号有误!");
        }
        if(!opus.getStatus().equals("待校级审核")){
            throw new BaseException("该作品状态不处于该环节!");
        }
        opus.setStatus("审核通过");
        InfoVO info = JwtUtils.getInfo(token);
        String[] strings = new String[1];
        strings[0] = iAuthorityService.getById(info.getRoles()[0]).getText();
        User user = iUserService.getById(info.getUid());
        String role = strings[0];
        String name = user.getName();

        Audit audit = new Audit();
        audit.setSynthesisID(opusID);
        audit.setAuditerRole(role);
        audit.setAuditerName(name);
        audit.setStatusChange("作品待校级审核->校级审核通过");
        audit.setAuditOpinion("通过");
        audit.setAuditerTime(LocalDateTime.now());
        auditService.addAudit(audit);
        return baseMapper.updateById(opus) == 1;
    }

    @Override
    public Boolean schoolCheckBack(String token,CheckBackDTO checkBackDTO) {
        String id = checkBackDTO.getID();
        Opus opus = iOpusService.getOpus(id);
        if (Objects.isNull(opus)){
            throw new BaseException("该作品编号有误!");
        }
        if(!opus.getStatus().equals("待校级审核")){
            throw new BaseException("该作品状态不处于该环节!");
        }
        opus.setStatus("被校级退回");
        opus.setReason(checkBackDTO.getReason());
        InfoVO info = JwtUtils.getInfo(token);
        String[] strings = new String[1];
        strings[0] = iAuthorityService.getById(info.getRoles()[0]).getText();
        User user = iUserService.getById(info.getUid());
        String role = strings[0];
        String name = user.getName();

        Audit audit = new Audit();
        audit.setSynthesisID(checkBackDTO.getID());
        audit.setAuditOpinion(checkBackDTO.getReason());
        audit.setAuditerRole(role);
        audit.setAuditerName(name);
        audit.setStatusChange("作品待校级审核->被校级退回");
        audit.setAuditerTime(LocalDateTime.now());
        auditService.addAudit(audit);
        return baseMapper.updateById(opus) == 1;
    }

    @Override
    public Boolean CommitOpus(String opusID) {
        Opus opus = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusID, opusID));
        if(Objects.isNull(opus)){
            throw new BaseException("作品编号有误!");
        }
        if(!opus.getStatus().equals("草稿") && !opus.getStatus().equals("被校级退回")){
            throw new BaseException("该作品不适用于该阶段!");
        }
        if(StrUtil.isEmpty(opus.getOpusName()) || StrUtil.isBlank(opus.getOpusName())){
            throw new BaseException("请输入作品名称");
        }
        if(StrUtil.isEmpty(opus.getOpusType()) || StrUtil.isBlank(opus.getOpusType())){
            throw new BaseException("请输入创作作品类型");
        }
        if(StrUtil.isEmpty(opus.getOrganization()) || StrUtil.isBlank(opus.getOrganization())){
            throw new BaseException("请输入所属机构");
        }
        if(StrUtil.isEmpty(opus.getPublicationLevel()) || StrUtil.isBlank(opus.getPublicationLevel())){
            throw new BaseException("请输入出版社等级");
        }
        if(StrUtil.isEmpty(opus.getPublicationName()) || StrUtil.isBlank(opus.getPublicationName())){
            throw new BaseException("请输入出版物名称");
        }
        if(StrUtil.isEmpty(opus.getClassifi()) || StrUtil.isBlank(opus.getClassifi())){
            throw new BaseException("请输入统计分类");
        }
        if(StrUtil.isEmpty(opus.getLeadAuthor()) || StrUtil.isBlank(opus.getLeadAuthor())){
            throw new BaseException("请输入第一作者");
        }
        if(StrUtil.isEmpty(opus.getPublicationNum()) || StrUtil.isBlank(opus.getPublicationNum())){
            throw new BaseException("请输入出版物面数（面");
        }
        if(StrUtil.isEmpty(opus.getOpusCate()) || StrUtil.isBlank(opus.getOpusCate())){
            throw new BaseException("请输入创作著作类别");
        }
        if(StrUtil.isEmpty(opus.getOpusOrigin()) || StrUtil.isBlank(opus.getOpusOrigin())){
            throw new BaseException("请输入作品来源");
        }
        if(StrUtil.isEmpty(opus.getResearchCate()) || StrUtil.isBlank(opus.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(opus.getFirstDiscipline()) || StrUtil.isBlank(opus.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
        if(StrUtil.isEmpty(opus.getSecondaryDiscipline()) || StrUtil.isBlank(opus.getSecondaryDiscipline())){
            throw new BaseException("请输入二级学科");
        }
        Opus one = super.getOne(Wrappers.lambdaQuery(Opus.class)
                .eq(Opus::getOpusName, opus.getOpusName()));
        if(Objects.nonNull(one) && !(one.getOpusID().equals(opus.getOpusID()))){
            throw new BaseException("作品名称重复!");
        }
        opus.setStatus("待校级审核");

        return baseMapper.updateById(opus) == 1;
    }

    @Override
    public IPage<Opus> userGetRelateOpus(UserDTO userDTO) {
        User user = iUserService.getOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getName, userDTO.getName()));
        if(Objects.isNull(user)){
            throw new BaseException("用户姓名有误!");
        }
        IPage<Opus> page = PageUtil.getPage(userDTO.getPageNum(), userDTO.getPageSize());

        LambdaQueryWrapper<Opus> wrapper = new LambdaQueryWrapper<>();
        if(user.getRole().equals("19177623324")){//判断身份如果是普通用户的话
            wrapper = Wrappers.lambdaQuery(Opus.class)
                    .eq(Opus::getEntered, userDTO.getName())
                    .or().eq(Opus::getLeadAuthor, userDTO.getName())
                    .or().like(Opus::getAllAuthor,userDTO.getName());
        }else if (user.getRole().equals("19185212210")){ // 如果是院级管理员 给他看本院的
            Dept dept = iDeptService.getById(user.getDept());
            wrapper = Wrappers.lambdaQuery(Opus.class)
                    .eq(Opus::getDept,dept.getDeptName());
        }else { // 校级管理员 看所有  给校级多提供一个字段——院系名字
            if(StrUtil.isEmpty(userDTO.getDept()) || StrUtil.isBlank(userDTO.getDept())){
                wrapper = Wrappers.lambdaQuery(Opus.class);
            }else {
                wrapper = Wrappers.lambdaQuery(Opus.class)
                        .eq(Opus::getDept,userDTO.getDept());
            }
        }

        IPage<Opus> opusIPage = baseMapper.selectPage(page, wrapper);
        List<Opus> records = opusIPage.getRecords();
//        IPage<PaperVO> paperVOIPage = iBeanService.copyPageProperties(paperIPage, PaperVO.class);
        ArrayList<Opus> opusList = new ArrayList<>();

        //对分页的设置
        int count = 1;
        int start = userDTO.getPageSize() * (userDTO.getPageNum()-1)+1;
        int end = userDTO.getPageNum() * userDTO.getPageSize();
        Collections.reverse(records);
        for (Opus record:records) {
            if (count >= start && count <= end){
                opusList.add(this.getOpus(record.getOpusID()));
//                paperList.add(this.getPaperVO(record.getPaperID()));
            }
            count += 1;
        }

//        Collections.reverse(opusList);
        opusIPage.setRecords(opusList);
        opusIPage.setTotal(records.size());

        return opusIPage;
    }

//    @Override
//    public float[] getFigure(UserDTO userDTO) {
//        float[] result = new float[5];
//        User user = iUserService.getOne(Wrappers.lambdaQuery(User.class)
//                .eq(User::getName, userDTO.getName()));
//
//        LambdaQueryWrapper<Opus> wrapper = new LambdaQueryWrapper<>();
//        if(user.getRole().equals("19177623324")){//判断身份如果是普通用户的话
//            wrapper = Wrappers.lambdaQuery(Opus.class)
//                    .eq(Opus::getEntered, userDTO.getName())
//                    .or().eq(Opus::getLeadAuthor, userDTO.getName())
//                    .or().like(Opus::getAllAuthor,userDTO.getName());
//        }else if (user.getRole().equals("19185212210")){ // 如果是院级管理员 给他看本院的
//            Dept dept = iDeptService.getById(user.getDept());
//            wrapper = Wrappers.lambdaQuery(Opus.class)
//                    .eq(Opus::getDept,dept.getDeptName());
//        }else { // 校级管理员 看所有  给校级多提供一个字段——院系名字
//            if(StrUtil.isEmpty(userDTO.getDept()) || StrUtil.isBlank(userDTO.getDept())){
//                wrapper = Wrappers.lambdaQuery(Opus.class);
//            }else {
//                wrapper = Wrappers.lambdaQuery(Opus.class)
//                        .eq(Opus::getDept,userDTO.getDept());
//            }
//        }
//        List<Opus> opusList = baseMapper.selectList(wrapper);
//
//        for (Opus opus : opusList) {
//            result[0] += opus.getScore();
//        }
//        return result;
//    }

    @Override
    public IPage<Opus> schoolUserGetOpus(UserDTO userDTO) {
        User one = iUserService.getOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getName, userDTO.getName()));
        if(Objects.isNull(one)){
            throw new BaseException("用户姓名有误!");
        }
        String dept = one.getDept();
        String deptName = iDeptService.getById(dept).getDeptName();
        String role = one.getRole();
        if(!role.equals("19190251173")){
            throw new BaseException("该用户权限不为校级审核员!");
        }
        IPage<Opus> page = PageUtil.getPage(userDTO.getPageNum(), userDTO.getPageSize());
        LambdaQueryWrapper<Opus> wrapper = Wrappers.lambdaQuery(Opus.class)
//                .eq(Paper::getDept,deptName)
                .and(wrapper1 -> wrapper1.eq(Opus::getStatus,"待校级审核"));

        IPage<Opus> opusIPage = baseMapper.selectPage(page, wrapper);
        List<Opus> records = opusIPage.getRecords();
//        IPage<PaperVO> paperVOIPage = iBeanService.copyPageProperties(paperIPage, PaperVO.class);
        ArrayList<Opus> opusList = new ArrayList<>();

        //对分页的设置
        int count = 1;
        int start = userDTO.getPageSize() * (userDTO.getPageNum()-1)+1;
        int end = userDTO.getPageNum() * userDTO.getPageSize();
        Collections.reverse(records);
        for (Opus record:records) {
            if (count >= start && count <= end){
//                this.getPaper(record.getPaperID())
                opusList.add(this.getOpus(record.getOpusID()));
            }
            count += 1;
        }

//        Collections.reverse(opusList);
        opusIPage.setRecords(opusList);
        opusIPage.setTotal(records.size());

        return opusIPage;
    }
}
